package pacman.objects;

import java.awt.Rectangle;

public abstract class Moveable extends Objects
{
  protected final float timeTick = 1;
  
  protected float charSize;
  protected float headingAngle,
                  speed;
  protected int health,
                maxHealth;
  protected boolean dead;

  public void updatePosition(int mapSizeX, int mapSizeY)
  {
    this.posX += this.speed * Math.cos(-this.headingAngle) / timeTick;
    this.posY += this.speed * Math.sin(-this.headingAngle) / timeTick;

    if (this.posX >= mapSizeX * cellSize)
      this.posX -= mapSizeX * cellSize;
    if (this.posX < 0)
      this.posX += mapSizeX * cellSize;

    if (this.posY >= mapSizeY * cellSize)
      this.posY -= mapSizeY * cellSize;
    if (this.posY < 0)
      this.posY += mapSizeY * cellSize;
  }

  public boolean isDead()
  {
    return this.dead;
  }

  public void kill()
  {
    this.dead = true;
    this.visible = false;
  }

  public void ressurect()
  {
    this.dead = false;
    this.visible = true;
    this.health = this.maxHealth;
  }

  public float getHeadingAngle()
  {
    return headingAngle;
  }

  public void setHeadingAngle(float headingAngle)
  {
    this.headingAngle = headingAngle;
  }

  public float getSpeed()
  {
    return speed;
  }

  public void setSpeed(float speed)
  {
    this.speed = speed;
  }

  public int getHealth()
  {
    return health;
  }

  public void setHealth(int health)
  {
    this.health = health;
  }

  public int getMaxHealth()
  {
    return maxHealth;
  }

  public void setMaxHealth(int maxHealth)
  {
    this.maxHealth = maxHealth;
  }

  public boolean  runMapHitTest(Static[][] map)
  {
    int x = (int)(posX + speed * Math.cos(-headingAngle) / timeTick - charSize * cellSize / 2);
    int y = (int)(posY + speed * Math.sin(-headingAngle) / timeTick - charSize * cellSize / 2);
    int wallX = x/cellSize;
    int wallY = y/cellSize;
    Rectangle pac = new Rectangle(x, y, (int)(charSize*cellSize), (int)(charSize*cellSize));
    Rectangle mapCell0, mapCell1, mapCell2;
    
    switch((int)(180*headingAngle/Math.PI))
    {
      case 0:
        wallX = x/cellSize;
        wallY = y/cellSize;
        if (wallX + 1 >= map.length)
          wallX = -1;
        mapCell0 = new Rectangle((wallX + 1)*cellSize,(wallY - 1)*cellSize, (int)cellSize, (int)cellSize);
        mapCell1 = new Rectangle((wallX + 1)*cellSize,(wallY)*cellSize, (int)cellSize, (int)cellSize);
        mapCell2 = new Rectangle((wallX + 1)*cellSize,(wallY + 1)*cellSize, (int)cellSize, (int)cellSize);
        if(map[wallX+1][wallY-1].isPassable() == false && pac.intersects(mapCell0) == true ||
           map[wallX+1][wallY].isPassable() == false && pac.intersects(mapCell1) == true ||
           map[wallX+1][wallY +1].isPassable() == false && pac.intersects(mapCell2) == true)
        {
          return true;
        }
        return false;

      case 90:
        wallX = x/cellSize;
        wallY = y/cellSize;
        if (wallY < 0)
          wallY = map[wallX].length-1;
        
        mapCell0 = new Rectangle((wallX - 1)*cellSize,(wallY)*cellSize, (int)cellSize, (int)cellSize);
        mapCell1 = new Rectangle((wallX)*cellSize,(wallY)*cellSize, (int)cellSize, (int)cellSize);
        mapCell2 = new Rectangle((wallX + 1)*cellSize,(wallY)*cellSize, (int)cellSize, (int)cellSize);
        if(map[wallX-1][wallY].isPassable() == false && pac.intersects(mapCell0) == true ||
           map[wallX][wallY].isPassable() == false && pac.intersects(mapCell1) == true ||
           map[wallX+1][wallY].isPassable() == false && pac.intersects(mapCell2) == true)
        {
          return true;
        }
        return false;

      case 180:
        wallX = x/cellSize;
        wallY = y/cellSize;
        if (wallX < 0)
          wallX = map.length-1;

        mapCell0 = new Rectangle((wallX)*cellSize,(wallY - 1)*cellSize, (int)cellSize, (int)cellSize);
        mapCell1 = new Rectangle((wallX)*cellSize,(wallY)*cellSize, (int)cellSize, (int)cellSize);
        mapCell2 = new Rectangle((wallX)*cellSize,(wallY + 1)*cellSize, (int)cellSize, (int)cellSize);
        if(map[wallX][wallY-1].isPassable() == false && pac.intersects(mapCell0) == true ||
           map[wallX][wallY].isPassable() == false && pac.intersects(mapCell1) == true ||
           map[wallX][wallY+1].isPassable() == false && pac.intersects(mapCell2) == true)
        {
          return true;
        }

      case 270:
        wallX = x/cellSize;
        wallY = y/cellSize;
        if (wallY + 1 >= map[wallX].length)
          wallY = -1;
        mapCell0 = new Rectangle((wallX - 1)*cellSize,(wallY+1)*cellSize, (int)cellSize, (int)cellSize);
        mapCell1 = new Rectangle((wallX)*cellSize,(wallY+1)*cellSize, (int)cellSize, (int)cellSize);
        mapCell2 = new Rectangle((wallX + 1)*cellSize,(wallY+1)*cellSize, (int)cellSize, (int)cellSize);
        if(map[wallX-1][wallY+1].isPassable() == false && pac.intersects(mapCell0) == true ||
           map[wallX][wallY+1].isPassable() == false && pac.intersects(mapCell1) == true ||
           map[wallX+1][wallY+1].isPassable() == false && pac.intersects(mapCell2) == true)
        {
          return true;
        }
        return false;
    }
    return false;
  }

  public boolean runGhostHitTest(Ghost ghost)
  {
    int x = (int)(posX + speed * Math.cos(-headingAngle) / timeTick - charSize * cellSize / 2);
    int y = (int)(posY + speed * Math.sin(-headingAngle) / timeTick - charSize * cellSize / 2);
    int wallX = x/cellSize;
    int wallY = y/cellSize;
    Rectangle pac = new Rectangle(x, y, (int)(charSize*cellSize), (int)(charSize*cellSize));
    Rectangle ghostRect = new Rectangle((int)(ghost.getPosX() - ghost.getCharSize() * cellSize / 2), (int)(ghost.getPosY() - ghost.getCharSize() * cellSize / 2), (int)(ghost.getCharSize()*cellSize), (int)(ghost.getCharSize()*cellSize));

    if(pac.intersects(ghostRect))
    {
      return true;
    }
    return false;
  }

  public float getCharSize() {
    return charSize;
  }
}